Objects, as used in the context of object-oriented programming, are programmatic combinations of data elements and methods. Each data element or method included in an object is either public or private. Public data elements and methods may be manipulated by entities that are external to the object. Private data elements and methods, on the other hand, are encapsulated and may only be manipulated by the object itself. In practice, a typical object includes some number of private data elements and some number of public methods for manipulating the private data elements.
Collection objects are used to organize collections of objects. Bags, a type of collection object, are so-named because their function is similar to real bags or sacks. Thus, programs put objects into bags and remove objects from bags. An object may be in a bag multiple times. This makes bags different than sets (another type of collection object) because an object is either in, or not in, a set. Bags are unlike arrays because the objects in a bag are not accessible using an index or key. Bags are also unlike queues or stacks because the order in which objects come out of a bag bears no defined relation to the order in which the objects went in to the bag.
In practice, the bag has been found to be a useful programming abstraction. This usefulness is enhanced if the bag is implemented as a transaction-protected resource. To understand the nature of transaction-protected resources and the usefulness of bags as transaction-protected resources, it is helpful to first understand the transaction abstraction. Fundamentally, a transaction is defined as a unit of work that is 1) "atomic," 2) "consistent," 3) "isolated," and 4) "durable" (more commonly, it is said that transactions have "ACID" properties).
To be "atomic" a transaction must complete in an all-or-none fashion. This means that transaction-protected resources must reflect all changes made during a transaction that successfully completes or "commits." It also means that transaction-protected resources must reflect none of the changes made during a transaction that fails to commit for any reason.
To be "consistent" a transaction must move transaction-protected resources from one consistent state to another. In systems that use the transaction abstraction, consistent states are defined in terms of rules known as integrity constraints. Transactions that violate these integrity constraints are aborted. In this way, transaction-protected resources are maintained in consistent states. For example, in a product inventory database, an integrity constraint could be used to abort any transaction that would result in a negative quantity of any product.
To be "isolated" the changes made to transaction protected resources must be invisible to threads and processes that are not associated with the transaction until the transaction has committed. Typically, isolation is achieved by locking the changed resource, forcing threads and processes that attempt to read the locked resource to wait until the transaction has completed.
Finally, to be "durable" the changes made to transaction-protected resources must not be lost or corrupted, even in the case of a catastrophic system failure. In this context, durability is not used in the absolute sense. For example, physically destroying the transaction processing computer system and all of its backup records will violate the durability property.
The implementation of bags as transaction-protected resources enhances the reliability of the bag objects and the overall reliability of the system using the bag objects. Unfortunately, in traditional implementations, ACID properties are ensured by limiting access to transaction protected resources to a single transaction at a time. Thus, only a single process or thread may access a particular bag at a particular time. It is easily appreciated, however, that the usefulness of an object, such as a bag, is greatly enhanced if it can participate in concurrent transactions. Specifically, provision of concurrent access ensures that the bag does not become a barrier that forces multiple processes to serialize. Thus, a need exists for a bag implementation that acts as a transaction-protected resource and still provides concurrent access to processes or thread.